package com.gitee.linzl.zuul.gateway.fiters.pre;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.linzl.zuul.gateway.fiters.AbstractJSONPreFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import com.netflix.zuul.http.ServletInputStreamWrapper;

import lombok.extern.slf4j.Slf4j;

/**
 * 公共参数校验,根据json中的method去调用对应的api
 * 
 * @description
 * @author linzl
 * @email 2225010489@qq.com
 * @date 2018年10月1日
 */
@Component
@Slf4j
public class ParameterValidateFilter extends AbstractJSONPreFilter {

	@Override
	public int filterOrder() {
		return 2;
	}

	@Override
	public Object run() throws ZuulException {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		try {
			InputStream is = request.getInputStream();
			String commonParam = StreamUtils.copyToString(is, Charset.forName(request.getCharacterEncoding()));
			if (log.isDebugEnabled()) {
				log.debug("访问地址:{},入参:{}", request.getRequestURL(), commonParam);
			}

			JSONObject param = JSON.parseObject(commonParam);
			// 校验param一些公共参数，如method是否为空，appid是否为空，签名是否正确

			String token = ctx.getZuulRequestHeaders().get(AuthTokenFilter.HEADER_TOKEN_NAME);
			param.put(AuthTokenFilter.HEADER_TOKEN_NAME, token);
			// 从token中解析出用户ID
			param.put("userId", ctx.get("userId"));

			byte[] bytes = param.toJSONString().getBytes();
			ctx.setRequest(new HttpServletRequestWrapper(request) {
				@Override
				public ServletInputStream getInputStream() throws IOException {
					return new ServletInputStreamWrapper(bytes);
				}

				@Override
				public int getContentLength() {
					return bytes.length;
				}

				@Override
				public long getContentLengthLong() {
					return bytes.length;
				}
			});

			String actualInvokeUrl = param.getString("method");
			if (StringUtils.isNotEmpty(actualInvokeUrl)) {
				actualInvokeUrl = "/" + actualInvokeUrl.replaceAll("\\.", "/");
				if (log.isDebugEnabled()) {
					log.debug("actualInvokeUrl:{}", actualInvokeUrl);
				}
				ctx.put(FilterConstants.FORWARD_TO_KEY, actualInvokeUrl);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
